package com.polaris.live.im.utils

import android.annotation.SuppressLint
import android.app.Service
import android.content.Context
import android.media.AudioManager
import android.os.Vibrator
import com.blankj.utilcode.util.StringUtils
import com.blankj.utilcode.util.TimeUtils
import com.polaris.live.App
import com.polaris.live.common.cacha.UserManager
import com.polaris.live.im.db.entity.SessionEntity
import com.polaris.live.im.sfs.TYPE_MESSAGE_CALL
import com.polaris.live.im.sfs.TYPE_MESSAGE_GIFT
import com.polaris.live.im.sfs.TYPE_MESSAGE_IMAGE
import com.polaris.live.im.sfs.TYPE_MESSAGE_INVITATION_ROOM
import com.polaris.live.im.sfs.TYPE_MESSAGE_NOTICE
import com.polaris.live.im.sfs.TYPE_MESSAGE_TEXT
import com.polaris.live.im.sfs.bean.chat.ext.SingleMessageExtBean
import com.polaris.live.translation.R.string
import com.polaris.live.utils.BitwiseUtils
import java.text.SimpleDateFormat
import java.util.Calendar
import java.util.Date
import java.util.Locale

/**
 * SessionUtils
 *
 * @author Created by lucas on 2023/10/20 12:02
 */
object SessionUtils {

    /**
     * 格式化会话列表的内容
     */
    fun formatSessionContext(item: SessionEntity): String? {
        val type = item.type ?: return null

        return formatSessionContext(type, item.senderId, item.content, item.extBean)
    }

    /**
     * 格式化会话列表的内容
     */
    fun formatSessionContext(type: Long, senderId: Long?, content: String?, extBean: SingleMessageExtBean?): String? {
        return when {
            BitwiseUtils.isBitwise(type, TYPE_MESSAGE_TEXT) -> {
                content
            }

            BitwiseUtils.isBitwise(type, TYPE_MESSAGE_IMAGE) -> {
                StringUtils.getString(string.session_content_photo)
            }

            BitwiseUtils.isBitwise(type, TYPE_MESSAGE_GIFT) -> {
                if (senderId != UserManager.getUserId()) {
                    "${StringUtils.getString(string.give_you)}[${extBean?.giftName}]"
                } else {
                    "${StringUtils.getString(string.you_send)}[${extBean?.giftName}]"
                }
            }

            BitwiseUtils.isBitwise(type, TYPE_MESSAGE_CALL) -> {
                StringUtils.getString(string.session_content_call)
            }

            BitwiseUtils.isBitwise(type, TYPE_MESSAGE_NOTICE) -> {
                content
            }

            BitwiseUtils.isBitwise(type, TYPE_MESSAGE_INVITATION_ROOM) -> {
                StringUtils.getString(string.session_room_invitation)
            }

            else -> {
                StringUtils.getString(string.session_content_unsupported)
            }
        }
    }

    /**
     * 格式化为会话时间
     */
    fun formatSessionTime(time: Long): String? {
        val date = Date(time)
        return try {
            val newDate = Date()
            if (!isSameYear(newDate, date)) {
                dateToString(date, "yyyy-MM-dd")
            } else {
                val dayNumber: Long = getDayNumber(newDate, date)
                if (dayNumber <= 0) {
                    if (isThreeMin(newDate, date)) {
                        StringUtils.getString(string.message_time_just)
                    } else {
                        dateToString(date, "HH:mm")
                    }
                } else if (dayNumber <= 1) {
                    val s: String = dateToString(date, "HH:mm")
                    StringUtils.getString(string.yesterday) + " " + s
                } else {
                    dateToString(date, "MM-dd HH:mm")
                }
            }
        } catch (e: Throwable) {
            "unknown"
        }
    }

    private fun isThreeMin(newDate: Date, oldDate: Date): Boolean {
        val calendar = Calendar.getInstance()
        calendar.time = newDate
        val newTime = calendar.timeInMillis
        calendar.time = oldDate
        val oldTime = calendar.timeInMillis
        return newTime - oldTime < 3 * 60 * 1000
    }

    fun getDayNumber(newDate: Date, oldDate: Date): Long {
        val newCalendar = Calendar.getInstance()
        newCalendar.time = newDate
        val oldCalendar = Calendar.getInstance()
        oldCalendar.time = oldDate
        return (newCalendar[Calendar.DAY_OF_YEAR] - oldCalendar[Calendar.DAY_OF_YEAR]).toLong()
    }

    fun isSameYear(newDate: Date, oldDate: Date): Boolean {
        val newCalendar = Calendar.getInstance()
        newCalendar.time = newDate
        val yearCalendar = Calendar.getInstance()
        yearCalendar.time = oldDate
        return newCalendar[Calendar.YEAR] == yearCalendar[Calendar.YEAR]
    }

    fun dateToString(data: Date, format: String): String {
        return SimpleDateFormat(format, Locale.ENGLISH).format(data)
    }

    fun periodMessageTime(time: Long): String? {
        return periodMessageTime(Date(time))
    }

    fun periodMessageTime(time: String): String? {
        return periodMessageTime(TimeUtils.string2Date(time))
    }

    /**
     * 格式化与当前时间间隔
     *
     * @param oldDate 旧的时间
     */
    fun periodMessageTime(oldDate: Date): String? {
        return try {
            val newDate = Date()
            if (!isSameYear(newDate, oldDate)) {
                dateToString(oldDate, "yyyy-MM-dd")
            } else {
                val dayNumber: Long = getDayNumber(newDate, oldDate)
                if (dayNumber <= 0) {
                    dateToString(oldDate, "HH:mm")
                } else if (dayNumber <= 1) {
                    val s: String = dateToString(oldDate, "HH:mm")
                    StringUtils.getString(string.yesterday) + " " + s
                } else if (dayNumber <= 7) {
                    dateToWeek(oldDate)
                } else {
                    dateToString(oldDate, "MM-dd")
                }
            }
        } catch (e: Throwable) {
            "unknown"
        }
    }

    /**
     * 获得当前日期是星期几
     */
    private fun dateToWeek(oldDate: Date): String {
        val calendar = Calendar.getInstance()
        calendar.time = oldDate
        return when (calendar[Calendar.DAY_OF_WEEK]) {
            1 -> StringUtils.getString(string.sunday)
            2 -> StringUtils.getString(string.monday)
            3 -> StringUtils.getString(string.tuesday)
            4 -> StringUtils.getString(string.wednesday)
            5 -> StringUtils.getString(string.thursday)
            6 -> StringUtils.getString(string.friday)
            7 -> StringUtils.getString(string.saturday)
            else -> ""
        }
    }

    @Volatile
    private var mTimestamp: Long = 0

    @Volatile
    private var mVibrator: Vibrator? = null

    /**
     * 前台收到消息响铃
     */
    fun noticeMessage() {
        val timestamp = System.currentTimeMillis()
        if (timestamp - mTimestamp <= 1000) {
            return
        }
        mTimestamp = timestamp

        vibrate()
    }

    @SuppressLint("MissingPermission")
    private fun vibrate() {
        if (isSilentMode()) {
            return
        }
        try {
            mVibrator?.cancel()
            mVibrator = App.instance.getSystemService(Service.VIBRATOR_SERVICE) as Vibrator
            mVibrator?.vibrate(longArrayOf(0, 300, 200, 300), -1)
        } catch (_: Throwable) {
        }
    }

    /**
     * 是否为静音模式
     */
    fun isSilentMode(): Boolean {
        val audioManager = App.instance.getSystemService(Context.AUDIO_SERVICE) as AudioManager
        return audioManager.ringerMode == AudioManager.RINGER_MODE_SILENT
    }
}